package cn.agiledata.bank.linkbank.impl.icbc;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayResponse;
import cn.agiledata.bank.linkbank.logic.DigitalSignValidatable;

public class IcbcB2bNetPayResponse extends AbstractBankPayResponse implements
        DigitalSignValidatable {
    private static final String[] RESPONSE_KEYS = {
            IcbcB2bNetConstant.INTERFACE_NAME,
            IcbcB2bNetConstant.INTERFACE_VERSION,
            IcbcB2bNetConstant.MERCHANT_ID, IcbcB2bNetConstant.MERCHANT_URL,
            IcbcB2bNetConstant.BANK_TRAN_NO, IcbcB2bNetConstant.RETURN_CODE,
            IcbcB2bNetConstant.ERROR_CODE, IcbcB2bNetConstant.ERROR_MESSAGE,
            IcbcB2bNetConstant.ORDER_ID, IcbcB2bNetConstant.AMOUNT,
            IcbcB2bNetConstant.CURRENCY_TYPE, IcbcB2bNetConstant.VERIFY_JOIN,
            IcbcB2bNetConstant.MERCHANT_JOIN, IcbcB2bNetConstant.CUSTOMER_JOIN,
            IcbcB2bNetConstant.CUSTOMER_JOIN_NUM,
            IcbcB2bNetConstant.RESULT_TYPE, IcbcB2bNetConstant.DATE,
            IcbcB2bNetConstant.NOTIFY_DATE,
            IcbcB2bNetConstant.MERCHANT_ACCOUNT,
            IcbcB2bNetConstant.MERCHANT_COLLECT_ACCOUNT,
            IcbcB2bNetConstant.MERCHANT_NAME };

    private String certFilePath;

    protected AbstractBankPayResponse getCopiedInstance() {
        IcbcB2bNetPayResponse response = new IcbcB2bNetPayResponse();
        response.certFilePath = this.certFilePath;
        return response;
    }

    protected String getSuccessReturnCode() {
        return IcbcB2bNetConstant.RETURN_CODE_SUCCESS;
    }

    public void setCertFilePath(String certFilePath) {
        this.certFilePath = certFilePath;
    }

    public void setMerchantName(String merchantName) {
        setMessage(IcbcB2bNetConstant.MERCHANT_NAME, merchantName);
    }

    public Date getDate() {
        String dateValue = getMessage(IcbcB2bNetConstant.DATE);
        return DateUtil.string2Date(dateValue, IcbcB2bNetConstant.DATE_FORMAT);
    }

    protected String[] getValidKeys() {
        return RESPONSE_KEYS;
    }

    protected boolean isValidKey(String key) {
        if (IcbcB2bNetConstant.RESPONSE_DIGITAL_SIGN.equals(key)) {
            return true;
        }
        if (IcbcB2bNetConstant.MERCHANT_NAME.equals(key)) {
            return false; // 收款账户名称由配置文件指定，不从银行反馈信息中读取
        }
        return super.isValidKey(key);
    }

    public BigDecimal getAmount() {
        try {
            BigDecimal hundred = new BigDecimal(100.0d);
            BigDecimal amount = new BigDecimal(
                    getMessage(IcbcB2bNetConstant.AMOUNT));
            amount = amount.divide(hundred, BigDecimal.ROUND_HALF_UP);
            return amount.setScale(2);
        } catch (Exception e) {
            return null;
        }
    }

    public String getOrderId() {
        return getMessage(IcbcB2bNetConstant.ORDER_ID);
    }

    public String getReturnCode() {
        return getMessage(IcbcB2bNetConstant.RETURN_CODE);
    }

    public String getReturnMessage() {
        return getMessage(IcbcB2bNetConstant.ERROR_MESSAGE);
    }

    public String getDigitalSign() {
        return getMessage(IcbcB2bNetConstant.RESPONSE_DIGITAL_SIGN);
    }

    public String getCryptoKeyDescription() {
        return null;
    }

    public boolean validateCryptoKey(String cryptoKey) {
        return true;
    }

    public boolean validateDigitalSign(String cryptoKey)
            throws LinkBankException {
        Map values = new HashMap();
        String[] keys = RESPONSE_KEYS;
        for (int i = 0; i < keys.length; i++) {
            values.put(keys[i], getMessage(keys[i]));
        }
        return IcbcNetPayUtils.validateDigitalSign(values, keys,
                getDigitalSign(), this.certFilePath);
    }

}
